Juno: Rework platform reset handler
authorSandrine Bailleux <[email protected]>
Wed, 18 Nov 2015 11:10:30 +0000 (11:10 +0000)
committerSandrine Bailleux <[email protected]>
Thu, 19 Nov 2015 14:53:58 +0000 (14:53 +0000)
This patch splits the Juno reset handler in 4 distinct pieces:

 - Detection of the board revision;
 - Juno R0 specific handler;
 - Juno R1 specific handler;
 - Juno R2 specific handler.

Depending on the board revision, the appropriate handler is called.
This makes the code easier to understand and maintain.

This patch is mainly cosmetic. The only functional change introduced
is that the Juno platform reset handler will now spin infinitely if
the board revision is not recognised. Previously, it would have
assumed that it was running on Juno R1 in this case.

Change-Id: I54ed77c4665085ead9d1573316c9c884d7d3ffa0

plat/arm/board/juno/aarch64/juno_helpers.S
plat/arm/board/juno/juno_def.h

index 263a980564876fbb8627c28648e179fc6712e810..ab06da2048ac6247f05a67408d42d39a1a23c226 100644 (file)
@@ -31,6 +31,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <bl_common.h>
+#include <cortex_a53.h>
 #include <cortex_a57.h>
 #include <v2m_def.h>
 #include "../juno_def.h"
        .globl  plat_reset_handler
        .globl  plat_arm_calc_core_pos
 
+#define JUNO_REVISION(rev)     REV_JUNO_R##rev
+#define JUNO_HANDLER(rev)      plat_reset_handler_juno_r##rev
+#define JUMP_TO_HANDLER_IF_JUNO_R(revision)    \
+       jump_to_handler JUNO_REVISION(revision), JUNO_HANDLER(revision)
+
        /* --------------------------------------------------------------------
-        * void plat_reset_handler(void);
+        * Helper macro to jump to the given handler if the board revision
+        * matches.
+        * Expects the Juno board revision in x0.
+        * --------------------------------------------------------------------
+        */
+       .macro jump_to_handler _revision, _handler
+       cmp     x0, #\_revision
+       b.eq    \_handler
+       .endm
+
+       /* --------------------------------------------------------------------
+        * Helper macro that reads the part number of the current CPU and jumps
+        * to the given label if it matches the CPU MIDR provided.
+        *
+        * Clobbers x0.
+        * --------------------------------------------------------------------
+        */
+       .macro  jump_if_cpu_midr _cpu_midr, _label
+       mrs     x0, midr_el1
+       ubfx    x0, x0, MIDR_PN_SHIFT, #12
+       cmp     w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+       b.eq    \_label
+       .endm
+
+       /* --------------------------------------------------------------------
+        * Platform reset handler for Juno R0.
         *
-        * For Juno r0:
+        * Juno R0 has the following topology:
+        * - Quad core Cortex-A53 processor cluster;
+        * - Dual core Cortex-A57 processor cluster.
+        *
+        * This handler does the following:
         * - Implement workaround for defect id 831273 by enabling an event
         *   stream every 65536 cycles.
         * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
         * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
-        *
-        * For Juno r1:
-        * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
-        * Note that:
-        * - The default value for the L2 Tag RAM latency for Cortex-A57 is
-        *   suitable.
-        * - Defect #831273 doesn't affect Juno r1.
         * --------------------------------------------------------------------
         */
-func plat_reset_handler
+func JUNO_HANDLER(0)
        /* --------------------------------------------------------------------
-        * Determine whether this code is running on Juno r0 or Juno r1.
-        * Keep this information in x2.
+        * Enable the event stream every 65536 cycles
         * --------------------------------------------------------------------
         */
-       /* Read the V2M SYS_ID register */
-       mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
-       ldr     w1, [x0]
-       /* Extract board revision from the SYS_ID */
-       ubfx    x1, x1, #V2M_SYS_ID_REV_SHIFT, #4
-       /*
-        * On Juno R0:  x2 := REV_JUNO_R0 - 1 = 0
-        * On Juno R1:  x2 := REV_JUNO_R1 - 1 = 1
+       mov     x0, #(0xf << EVNTI_SHIFT)
+       orr     x0, x0, #EVNTEN_BIT
+       msr     CNTKCTL_EL1, x0
+
+       /* --------------------------------------------------------------------
+        * Nothing else to do on Cortex-A53.
+        * --------------------------------------------------------------------
         */
-       sub     x2, x1, #1
+       jump_if_cpu_midr CORTEX_A53_MIDR, 1f
 
        /* --------------------------------------------------------------------
-        * Determine whether this code is executed on a Cortex-A53 or on a
-        * Cortex-A57 core.
+        * Cortex-A57 specific settings
         * --------------------------------------------------------------------
         */
-       mrs     x0, midr_el1
-       ubfx    x1, x0, MIDR_PN_SHIFT, #12
-       cmp     w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
-       b.eq    A57
+       mov     x0, #((L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT) | \
+                     (L2_TAG_RAM_LATENCY_3_CYCLES << L2CTLR_TAG_RAM_LATENCY_SHIFT))
+       msr     L2CTLR_EL1, x0
+1:
+       isb
+       ret
+endfunc JUNO_HANDLER(0)
 
-       /* Nothing needs to be done for the Cortex-A53 on Juno r1 */
-       cbz     x2, apply_831273
+       /* --------------------------------------------------------------------
+        * Platform reset handler for Juno R1.
+        *
+        * Juno R1 has the following topology:
+        * - Quad core Cortex-A53 processor cluster;
+        * - Dual core Cortex-A57 processor cluster.
+        *
+        * This handler does the following:
+        * - Set the L2 Data RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
+        *
+        * Note that:
+        * - The default value for the L2 Tag RAM latency for Cortex-A57 is
+        *   suitable.
+        * - Defect #831273 doesn't affect Juno R1.
+        * --------------------------------------------------------------------
+        */
+func JUNO_HANDLER(1)
+       /* --------------------------------------------------------------------
+        * Nothing to do on Cortex-A53.
+        * --------------------------------------------------------------------
+        */
+       jump_if_cpu_midr CORTEX_A57_MIDR, A57
        ret
 
 A57:
@@ -92,30 +140,48 @@ A57:
         * Cortex-A57 specific settings
         * --------------------------------------------------------------------
         */
-
-       /* Change the L2 Data RAM latency to 3 cycles */
-       mov     x0, #L2_DATA_RAM_LATENCY_3_CYCLES
-       cbnz    x2, apply_l2_ram_latencies
-       /* On Juno r0, also change the L2 Tag RAM latency to 3 cycles */
-       orr     x0, x0, #(L2_TAG_RAM_LATENCY_3_CYCLES <<                \
-                               L2CTLR_TAG_RAM_LATENCY_SHIFT)
-apply_l2_ram_latencies:
+       mov     x0, #(L2_DATA_RAM_LATENCY_3_CYCLES << L2CTLR_DATA_RAM_LATENCY_SHIFT)
        msr     L2CTLR_EL1, x0
+       isb
+       ret
+endfunc JUNO_HANDLER(1)
 
-       /* Juno r1 doesn't suffer from defect #831273 */
-       cbnz    x2, ret
-
-apply_831273:
        /* --------------------------------------------------------------------
-        * On Juno r0, enable the event stream every 65536 cycles
+        * Platform reset handler for Juno R2.
+        *
+        * Juno R2 has the following topology:
+        * - Quad core Cortex-A53 processor cluster;
+        * - Dual core Cortex-A72 processor cluster.
+        *
+        * This handler does nothing.
         * --------------------------------------------------------------------
         */
-       mov     x0, #(0xf << EVNTI_SHIFT)
-       orr     x0, x0, #EVNTEN_BIT
-       msr     CNTKCTL_EL1, x0
-ret:
-       isb
+func JUNO_HANDLER(2)
        ret
+endfunc JUNO_HANDLER(2)
+
+       /* --------------------------------------------------------------------
+        * void plat_reset_handler(void);
+        *
+        * Determine the Juno board revision and call the appropriate reset
+        * handler.
+        * --------------------------------------------------------------------
+        */
+func plat_reset_handler
+       /* Read the V2M SYS_ID register */
+       mov_imm x0, (V2M_SYSREGS_BASE + V2M_SYS_ID)
+       ldr     w1, [x0]
+       /* Extract board revision from the SYS_ID */
+       ubfx    x0, x1, #V2M_SYS_ID_REV_SHIFT, #4
+
+       JUMP_TO_HANDLER_IF_JUNO_R(0)
+       JUMP_TO_HANDLER_IF_JUNO_R(1)
+       JUMP_TO_HANDLER_IF_JUNO_R(2)
+
+       /* Board revision is not supported */
+not_supported:
+       b       not_supported
+
 endfunc plat_reset_handler
 
        /* -----------------------------------------------------
index 143cf00a0571baeb8d9d1e0ba7238fac946a0ee5..1f367f274d38e67ed56ea451d51c387ab69c9c04 100644 (file)
@@ -39,6 +39,7 @@
 /* Board revisions */
 #define REV_JUNO_R0                    0x1     /* Rev B */
 #define REV_JUNO_R1                    0x2     /* Rev C */
+#define REV_JUNO_R2                    0x3     /* Rev D */
 
 /* Bypass offset from start of NOR flash */
 #define BL1_ROM_BYPASS_OFFSET          0x03EC0000